package com.gushen.library;

import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.opengl.EGL14;
import android.opengl.EGLContext;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import com.gushen.library.filter.CameraFilter;
import com.gushen.library.filter.ScreenFilter;
import com.gushen.library.filter.TimeFilter;
import com.gushen.library.utils.FileUtils;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import java.io.IOException;

public class CameraRenderer implements GLSurfaceView.Renderer,
        SurfaceTexture.OnFrameAvailableListener, Camera.PreviewCallback {
    private MySurfaceView mySurfaceView;
    private CameraHelper mCameraHelper;
    private float[] mtx = new float[16];
    private int[] mTextures;

    private SurfaceTexture mSurfaceTexture;
    private CameraFilter mCameraFilter;
    private ScreenFilter mScreenFilter;
    private TimeFilter timeFilter;
    private MediaRecorder mMediaRecorder;

    public CameraRenderer(MySurfaceView surfaceView) {
        this.mySurfaceView = surfaceView;

    }

    /**
     * 画布创建好啦
     *
     * @param gl
     * @param config
     */
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

        mCameraHelper = new CameraHelper(Camera.CameraInfo.CAMERA_FACING_BACK);
        mCameraHelper.setPreviewCallback(this);

        // 初始化纹理ID数组，如果需要使用OpenGL纹理，这部分代码是必要的。
        mTextures = new int[1];
        // 初始化纹理ID数组，作用：生成一个纹理ID并存储到 mTextures 数组中。如果需要使用OpenGL纹理，这部分代码是必要的。
        GLES20.glGenTextures(mTextures.length, mTextures, 0);

        // 创建一个与生成的纹理ID关联的SurfaceTexture对象
        //SurfaceTexture 是 Android 平台上用于处理纹理相关的视频输入的一个类。它主要用于以下几个方面：
        //视频输入和纹理渲染：可以用来接收来自摄像头或其他视频源的数据，并将其作为 OpenGL 纹理进行渲染。
        //异步更新：支持异步更新纹理内容，这意味着可以在不阻塞主线程的情况下更新纹理数据。
        //帧可用监听：可以通过设置 OnFrameAvailableListener 监听器来获取新帧可用的通知。
        //如果需要通过 SurfaceTexture 处理视频输入或摄像头数据，这部分代码是必要的。
        mSurfaceTexture = new SurfaceTexture(mTextures[0]);
        // 设置帧可用监听器，当有新的帧可用时将调用onFrameAvailable方法
        mSurfaceTexture.setOnFrameAvailableListener(this);

        mCameraFilter = new CameraFilter(mySurfaceView.getContext());
        mScreenFilter = new ScreenFilter(mySurfaceView.getContext());
        timeFilter = new TimeFilter(mySurfaceView.getContext());

        //渲染线程的EGL上下文
        EGLContext eglContext = EGL14.eglGetCurrentContext();
        mMediaRecorder = new MediaRecorder(mySurfaceView.getContext(), FileUtils.getOutputFilePath(),
                CameraHelper.HEIGHT, CameraHelper.WIDTH, eglContext);
    }

    /**
     * 画布发生了改变
     *
     * @param gl
     * @param width
     * @param height
     */
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        if (mSurfaceTexture != null){
            mSurfaceTexture.setDefaultBufferSize(width, height);
        }

        //开启预览
        mCameraHelper.startPreview(mSurfaceTexture);
        mCameraFilter.onReady(width, height);
        mScreenFilter.onReady(width, height);
        timeFilter.onReady(width, height);
        if (mWatermarkConfig != null){
            timeFilter.setWaterMarkConfig(mWatermarkConfig);
        }
    }

    /**
     * 开始画画吧
     *
     * @param gl
     */
    @Override
    public void onDrawFrame(GL10 gl) {

        // 设置清空屏幕的颜色值为黑色，并清空颜色缓冲区
        GLES20.glClearColor(0, 0, 0, 0);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        // 更新SurfaceTexture的图像数据
        // 更新纹理，然后我们才能够使用opengl从SurfaceTexure当中获得数据 进行渲染
        mSurfaceTexture.updateTexImage();
        //surfaceTexture 比较特殊，在opengl当中 使用的是特殊的采样器 samplerExternalOES （不是sampler2D）

        // 获取当前SurfaceTexture的变换矩阵，并将其应用到相机滤镜
        mSurfaceTexture.getTransformMatrix(mtx);
        mCameraFilter.setMatrix(mtx);

        // 使用相机滤镜绘制图像帧，并返回绘制后的纹理ID
        int id = mCameraFilter.onDrawFrame(mTextures[0]);

        id = timeFilter.onDrawFrame(id);
        if (FileUtils.isHarmonyOS()){
            id = timeFilter.onDrawFrame(id);
            id = timeFilter.onDrawFrame(id);
            id = timeFilter.onDrawFrame(id);
        }

        // 使用屏幕滤镜绘制经过相机滤镜处理的图像帧
        mScreenFilter.onDrawFrame(id);

        //进行录制
        mMediaRecorder.encodeFrame(id, mSurfaceTexture.getTimestamp());
    }




    /**
     * surfaceTexture 有一个有效的新数据的时候回调
     *
     * @param surfaceTexture
     */
    @Override
    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
        mySurfaceView.requestRender();
    }

    public void onSurfaceDestroyed() {
        if (mCameraHelper != null){
            mCameraHelper.stopPreview();
        }
    }

    private WatermarkConfig mWatermarkConfig;
    public void setWatermarkConfig(WatermarkConfig config) {
        this.mWatermarkConfig = config;
        if (timeFilter != null){
            timeFilter.setWaterMarkConfig(config);
        }
    }

    public void startRecord(float speed) {
        try {
            mMediaRecorder.start(speed);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void stopRecord(RecorderCallBack callBack) {
        if (mMediaRecorder != null){
            mMediaRecorder.stop(callBack);
        }
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        // data 可以做人脸识别

    }

}
